<template>
  <div>
    <audio
      ref="audio"
      @pause="onPause"
      @play="onPlay"
      @timeupdate="onTimeUpdate"
      controls
      @loadedmetadata="onLoadedMetaData"
      src="@/assets/a.mp3"></audio>
    <hr/>
    <!-- 此处的ref属性，可以很方便的在vue组件中通过 this.$refs.audio获取该dom元素 -->
    <div style="display: flex;justify-content: center;align-items: flex-end">
      <!-- 音频播放控件 -->
      <el-button
        type="primary"
        @click="startPlayOrPause"
      >{{audio.playing | transPlayPause}}
      </el-button>

      <div>
        进度显示：
        <el-tag type="info">{{audio.currentTime | formatSecond}} / {{audio.maxTime | formatSecond}}</el-tag>
      </div>
      <div style="display: flex; align-items: flex-end">
        进度条：
        <el-slider
          vertical
          height="60px"
          v-model="sliderTime"
          :format-tooltip="formatProcessToolTip"
          @change="changeCurrentTime"
          class="slider"
        ></el-slider>
      </div>
      <div style="display: flex; align-items: flex-end">
        音量控制：
        <el-slider
          vertical
          :format-tooltip="formatVolumeToolTip"
          @change="changeVolume"
          v-model="sliderVolume"
          height="60px"
          class="slider"
        ></el-slider>
      </div>
      <div>
        静音：
        <el-switch
          v-model="switchValue"
          active-color="#13ce66"
          inactive-color="#ccc"
          @change="handleSwitch"
        ></el-switch>
      </div>
      <div>
        速度控制:
        <el-select v-model="speedSelect" placeholder="请选择速度" @change="selectChange">
          <el-option
            v-for="(item,index) in [.5, .75, 1, 1.25, 1.5, 2]"
            :key="index"
            :label="item"
            :value="item"
          ></el-option>
        </el-select>
      </div>
      <div>
        <a type="primary" :href="audio.downloadUrl" target="_blank" class="download" download>下载</a>
      </div>
    </div>

  </div>
</template>

<script>
// 整数格式化成 时:分:秒
function realFormatSecond(second) {
  var secondType = typeof second;
  if (secondType === 'number' || secondType === 'string') {
    second = parseInt(second);
    var hours = Math.floor(second / 3600);
    second = second - hours * 3600;
    var minute = Math.floor(second / 60);
    second = second - minute * 60;
    return hours + ":" + ('0' + minute).slice(-2) + ":" + ('0' + second).slice(-2)
  } else {
    return '0:00:00';
  }
}

/**
 * 两个重要事件：
 * loadedmetadata: 代表音频的元数据已经被加载完成，可以从中获取音频总时长
 * timeupdate: 当前播放位置作为正常播放的一部分而改变，或者以特别有趣的方式，
 * 例如不连续地改变，可以从该事件中获取音频的当前播放时间，
 * 该事件在播放过程中会不断被触发

 */

export default {
  props: {
    theUrl: {
      type: String,
    },
    theSpeeds: {
      type: Array,
      default() {
        return [1, 1.5, 2]
      }
    },
    theControlList: {
      type: String,
    }
  },
  name: "VueAudio",
  data() {
    return {
      url: this.theUrl,
      audio: {
        // 该字段是音频是否处于播放状态的属性
        playing: false,
        // 音频当前播放时长
        currentTime: 0,
        // 音频最大播放时长
        maxTime: 0,
        // 有声音 -false，静音-true
        muted: false,
        // 下载链接
        downloadUrl: ''
      },
      sliderTime: 0,
      speeds: this.theSpeeds,
      sliderVolume: 60,
      switchValue: false,
      speedSelect: 1,
      controlList: {
        // 不显示下载
        noDownload: false,
        // 不显示静音
        noMuted: false,
        // 不显示音量条
        noVolume: false,
        // 不显示进度条
        noProcess: false,
        // 只能播放一个
        onlyOnePlaying: false,
        // 不要快进按钮
        noSpeed: false
      }
    }
  },
  mounted() {
    this.audio.downloadUrl = this.$refs.audio.src
  },
  methods: {
    // 控制音频的播放与暂停
    startPlayOrPause() {
      return this.audio.playing ? this.pause() : this.play()
    },
    // 播放音频
    play() {
      this.$refs.audio.play();
    },
    // 暂停音频
    pause() {
      this.$refs.audio.pause();
    },
    // 当音频播放
    onPlay() {
      this.audio.playing = true;
    },
    // 当音频暂停
    onPause() {
      this.audio.playing = false;
    },
    // 当timeUpdate事件大概每秒一次，用来更新音频流的当前播放时间
    onTimeUpdate(res) {
      console.log('timeUpdate');
      console.log(res);
      this.audio.currentTime = res.target.currentTime;
      // 当音频当前时间改变后，进度条也要改变
      this.sliderTime = this.audio.currentTime / this.audio.maxTime * 100
    },
    // 当加载语音流元数据完成后，会触发该事件的回调函数
    // 语音元数据主要是语音的长度之类的数据
    onLoadedMetaData(res) {
      console.log('onLoadedMetaData');
      console.log(res);
      this.audio.maxTime = parseInt(res.target.duration);
    },
    // 拖动进度条，改变当前时间，index是进度条改变时的回调函数的参数0-100之间，需要换算成实际时间
    changeCurrentTime(index) {
      this.$refs.audio.currentTime = index / 100 * this.audio.maxTime
    },
    // 进度条格式化toolTip
    formatProcessToolTip(index = 0) {
      index = this.audio.maxTime / 100 * index;
      return '进度条：' + realFormatSecond(index);
    },
    // 设置 controlList
    setControlList() {
      let controlList = this.theControlList.split(' ');
      controlList.forEach(item => {
        if (this.controlList[item] !== undefined) {
          this.controlList[item] = true;
        }
      })
    },
    changeSpeed() {
      let index = this.speeds.indexOf(this.audio.speed) + 1;
      this.audio.speed = this.speeds[index % this.speeds.length];
      this.$refs.audio.playbackRate = this.audio.speed;
    },
    // 音量条toolTip
    formatVolumeToolTip(index) {
      return '音量条: ' + index
    },
    // 音量改变
    changeVolume(index = 0) {
      // volume 属性设置或返回音频的音量，从 0.0 (静音) 到 1.0 (最大声)。
      this.$refs.audio.volume = index / 100
      this.sliderVolume = index
    },
    handleSwitch(){
      this.$refs.audio.muted = this.switchValue;
    },
    selectChange(){
      console.log(this.speedSelect)
      this.$refs.audio.playbackRate = this.speedSelect;
    }
  },
  filters: {
    // 使用组件过滤器来动态改变按钮的显示
    transPlayPause(value) {
      return value ? '暂停' : '播放'
    },
    // 将整数转化成时分秒
    formatSecond(second = 0) {
      return realFormatSecond(second);
    }
  },
  created() {
    this.setControlList();
  }
}
</script>

<style scoped>

</style>